package processes;

import java.util.ArrayList;
	/**
	 * Provides methods to manipulate with structure of processes repository.
	 * Manages processes.
	 * @author Miroslav Vozabal
	 *
	 */
	public class ProcessesManager {
	private ProcessesRepository pdList;

	/**
	 * Constructor.
	 */
	public ProcessesManager() {
		pdList = new ProcessesRepository();
	}
	
	/**
	 * Creates processes of pdList from ArrayList.
	 * @param list
	 */
	public void createProcesses(ArrayList<ProcessDescriptor> list) {
		pdList.addItems(list);
	}

	/**
	 * Prints processes.
	 * @return string with processes.
	 */
	public String printProcesses() {
		return pdList.printListInversely();
	}
	
	/**
	 * Kills all processes from position of id.
	 * @param id
	 */
	public void killProcess(int id) {
		ProcessDescriptor pd = pdList.findItem(id);
		ProcessDescriptor killer = getTail(); //Disconnects kill process from the repository.
		cleanLastProccesRefference();
		killProcess(pd);
		ArrayList<ProcessDescriptor> oneItemList = new ArrayList<ProcessDescriptor>();
		oneItemList.add(killer); 
		createProcesses(oneItemList); //Connects kill process back to the repository.
	}
	
	/**
	 * Recursion killing of processes. Kills process and processes in its all subtrees. 
	 * Doesn't handle with adding children at any brother position.
	 * @param processDescriptor
	 */
	private void killProcess(ProcessDescriptor processDescriptor) { 
		if (processDescriptor.getChildren() == null) {
			processDescriptor.getThread().stop();
			pdList.cleanItem(processDescriptor);
		}
		else {
			killProcess(processDescriptor.getChild(0));			
			processDescriptor.getThread().stop();
			pdList.cleanItem(processDescriptor);
		}		
	}
	/**
	 * Kills processes of last parent.
	 */
	public void killLastParentProcesses() {
		ProcessDescriptor pd = pdList.getTail();
		 while (pd.getSibling() != null) {
			 pd.getThread().stop();
			 pd = pd.getSibling();
			 pdList.cleanTail();
		 }
		 pd.getThread().stop();
		 pdList.cleanTail();
	}
	
	
	/**
	 * Gets tail of processes repository.
	 * @return
	 */
	public ProcessDescriptor getTail(){
		return pdList.getTail();
	}
	
	/**
	 * Erases the last item of processes in the processes repository without ending of thread.
	 * It's supposed that the tread was ended by itself. It's to need erase item where are stored information about proccess.
	 */
	public void cleanLastProccesRefference() {
		pdList.cleanTail();		
	}
	
	/**
	 * Gets the process that is connected with id.
	 * @param id
	 */
	public ProcessDescriptor getProcess(int id) {
		return pdList.findItem(id);
	}

	
	/**
	 * Gets the parent process that is connected with id.
	 * @param id
	 */
	public ProcessDescriptor getParentProcess(int id) {
		return pdList.findItem(id).getParent();
	}
}
